package edu.gatech.stolen.tea.display.item;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import android.util.Log;
import android.view.KeyEvent;

import edu.gatech.stolen.tea.Accounts;
import edu.gatech.stolen.tea.ItemEditor;
import edu.gatech.stolen.tea.R;
import edu.gatech.stolen.tea.SimpleOverlay;
//import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;

/**
 * This class displays google map
 * 
 * @author Leshi
 * 
 */
public class MapDisplayActivity extends MapActivity {
	/**
	 * the map view
	 */
	MapView mapView;
	/**
	 * the map controller
	 */
	MapController mc;
	/**
	 * the geopoint location to display
	 */
	GeoPoint p;
	/**
	 * geocoder
	 */
	Geocoder gc;
	
	private Accounts accounts= new Accounts();

	/**
	 * this is called when activity starts creates a mapview and default zoom to
	 * GT
	 */
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.viewmap);
		accounts=accounts.loadData(getFilesDir().toString());
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.setSatellite(true);
		
		//display location stuff
		gc = new Geocoder(this);
		String inputAddress = accounts.itemEditor.getItem(accounts.itemEditor.currentItemName).getLocation();
		JSONObject locationObj = getLocationInfo(inputAddress);
		p = getLatLong(locationObj);
		mc = mapView.getController();
		mc.animateTo(p);
		mc.setZoom(17);
		
		
		//map overlay stuff
		List<Overlay> mapOverlays = mapView.getOverlays();
		Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
		SimpleOverlay itemizedoverlay = new SimpleOverlay(drawable, this);
		OverlayItem overlayItem = new OverlayItem(p,"Destination",inputAddress);
		itemizedoverlay.addOverlay(overlayItem);
		mapOverlays.add(itemizedoverlay);
		
		
		mapView.invalidate();
		
//		try {
//			List<Address> foundAddress = gc
//					.getFromLocationName(inputAddress, 1);
//			if (foundAddress.size() == 0) { // if no address found, display an
//												// error
////				Dialog locationError = new AlertDialog.Builder(
////						MapDisplayActivity.this).setIcon(0).setTitle("Error")
////						.setPositiveButton(R.string.ok, null)
////						.setMessage("Sorry, your address doesn't exist.")
////						.create();
////				locationError.show();
//				Log.d("MAP", "location doesnt exist");
//			} else {
//				Address itemAddress = foundAddress.get(0);
//				Double lat = itemAddress.getLatitude();
//				Double lng = itemAddress.getLongitude();
//				navigateToLocation(lat.intValue(), lng.intValue(), mapView);
//			}
//		} catch (IOException e) {
//			Log.d("MAP", "can't find address "+inputAddress);
//			e.printStackTrace();
//		}

	}

	/**
	 * what to do when key is pressed
	 * 
	 * @param keyCode
	 *            the key
	 * @param event
	 */
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_3: // press 3 to zoom in
			mc.zoomIn();
			break;
		case KeyEvent.KEYCODE_1: // press 1 to zoom out
			mc.zoomOut();
			break;
		}
		return super.onKeyDown(keyCode, event);

	}

	/**
	 * to display the route default set to false
	 * 
	 * @return false do not display route
	 */
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * Navigates a given MapView to the specified lat and lng
	 * 
	 * @param latitude
	 * @param longitude
	 * @param mv
	 *            the MapView
	 */
	public static void navigateToLocation(int latitude, int longitude,
			MapView mv) {
		GeoPoint p = new GeoPoint(latitude, longitude); // new GeoPoint
		MapController mc = mv.getController();
		mc.animateTo(p); // move map to the given point
		//int zoomlevel = mv.getMaxZoomLevel(); // detect maximum zoom level
		//mc.setZoom(zoomlevel - 1); // zoom
		mc.setZoom(17);
		//mv.setSatellite(false); // display only "normal" mapview
	}
	
	/**
	 * returns a adress to be turned into a GeoPoint
	 * @param address string
	 * @return a JSONObject containing the address
	 */
	public static JSONObject getLocationInfo(String address) {
	    StringBuilder stringBuilder = new StringBuilder();
	    try {

	    address = address.replaceAll(" ","%20");    

	    HttpPost httppost = new HttpPost("http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false");
	    HttpClient client = new DefaultHttpClient();
	    HttpResponse response;
	    stringBuilder = new StringBuilder();


	        response = client.execute(httppost);
	        HttpEntity entity = response.getEntity();
	        InputStream stream = entity.getContent();
	        int b;
	        while ((b = stream.read()) != -1) {
	            stringBuilder.append((char) b);
	        }
	    } catch (ClientProtocolException e) {
	    } catch (IOException e) {
	    }

	    JSONObject jsonObject = new JSONObject();
	    try {
	        jsonObject = new JSONObject(stringBuilder.toString());
	    } catch (JSONException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	    }

	    return jsonObject;
	}
	
	/**
	 * returns a GeoPoint to display
	 * @param jsonObject
	 * @return
	 */
	public static GeoPoint getLatLong(JSONObject jsonObject) {

        Double lon = new Double(0);
        Double lat = new Double(0);

        try {

            lon = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
                .getJSONObject("geometry").getJSONObject("location")
                .getDouble("lng");

            lat = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
                .getJSONObject("geometry").getJSONObject("location")
                .getDouble("lat");

        } catch (Exception e) {
            e.printStackTrace();

        }

        return new GeoPoint((int) (lat * 1E6), (int) (lon * 1E6));
    }

}
